home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / x / animutil / xanim229.lha / xanim / xanim_iff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-08  |  42.0 KB  |  1,595 lines

  1.  
  2. /*
  3.  * xanim_iff.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed
  9.  * without fee provided that this copyright notice is preserved 
  10.  * intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include <stdio.h>
  19. #include "mytypes.h"
  20. #include "xanim.h"
  21. #include "xanim_iff.h"
  22.  
  23. void IFF_Read_File();
  24. void IFF_Adjust_For_EHB();
  25. void IFF_Adjust_For_HAM();
  26. void IFF_Read_BODY();
  27. LONG IFF_Read_Garb();
  28. void IFF_Print_ID();
  29. void IFF_Deltal();
  30. void IFF_Delta3();
  31. void IFF_Delta5();
  32. LONG IFF_DeltaJ();
  33. void IFF_Byte_Mod();
  34. void IFF_Short_Mod();
  35. void IFF_HAM_To_332();
  36. LONG Is_IFF_File();
  37. void IFF_Buffer_Action();
  38. ULONG IFF_Get_Word();
  39. ULONG IFF_Get_HalfWord();
  40.  
  41.  
  42. #define HMAP_SIZE 16
  43. #define IFF_SPEED_DEFAULT 3
  44.  
  45. static LONG mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  46. extern ACT_IFF_DLTA_HDR old_dlta[];
  47.  
  48. /*
  49.  *
  50.  */
  51. void IFF_Read_File(fname)
  52. BYTE *fname;
  53. {
  54.  FILE *fin;
  55.  LONG j;
  56.  LONG camg_flag,cmap_flag,ret,compression;
  57.  LONG crng_flag,cmap_action,formtype;
  58.  LONG ansq_flag,ansq_cnt,dlta_cnt;
  59.  LONG body_1,dlta_2;
  60.  LONG bmhd_flag;
  61.  Bit_Map_Header bmhd;
  62.  Chunk_Header  chunk;
  63.  Anim_Header   anhd;
  64.  LONG *ansq_dnum,*ansq_tim,*dlta_act;
  65.  LONG prop_flag;
  66.  LONG exit_flag;
  67.  LONG iff_imagex,iff_imagey;
  68.  Face_Header face;
  69.  
  70.  dlta_2 = -2;
  71.  body_1 = -1;
  72.  compression=0;
  73.  anim_flags &= (~ANIM_HAM);
  74.  iff_imagex=0;
  75.  iff_imagey=0;
  76.  prop_flag=0;
  77.  bmhd_flag=0;
  78.  crng_flag=0;
  79.  camg_flag=0;
  80.  cmap_flag=0;
  81.  ansq_flag=0;
  82.  ansq_cnt=0;
  83.  ansq_dnum=0;
  84.  ansq_tim=0;
  85.  dlta_act=0;
  86.  dlta_cnt=0;
  87.  action[action_cnt].type = ACT_CMAP;
  88.  action[action_cnt].time = 0;
  89.  action[action_cnt].data = 0;
  90.  cmap_action = action_cnt;
  91.  action_cnt++;
  92.  
  93.  if ( (fin=fopen(fname,"r")) == 0)
  94.  { 
  95.   fprintf(stderr,"can't open %s\n",fname); 
  96.   TheEnd();
  97.  }
  98.  
  99.  exit_flag = 0; 
  100.  while( !feof(fin) && !exit_flag)
  101.  {
  102.   /* read Chunk_Header 
  103.    */
  104.   chunk.id   = IFF_Get_Word(fin);
  105.   chunk.size = IFF_Get_Word(fin);
  106.  
  107.   if (chunk.size == -1) ret = -1;
  108.   else ret = 0;
  109.  
  110.   if (debug_flag) 
  111.   {
  112.    fprintf(stderr,"Chunk.ID = ");
  113.    IFF_Print_ID(stderr,chunk.id);
  114.    fprintf(stderr,"  chunksize=%lx\n",chunk.size);
  115.   }
  116.   if (chunk.size & 1) chunk.size+=1; /* halfword pad it */
  117.   if (ret==0)
  118.   {
  119.    switch(chunk.id)
  120.    {
  121.     case PROP: 
  122.         prop_flag=1;
  123.     case LIST: 
  124.     case FORM: 
  125.                 formtype = IFF_Get_Word(fin);
  126.         if (debug_flag) 
  127.                 {
  128.                  fprintf(stderr,"  IFF ",formtype);
  129.                  IFF_Print_ID(stderr,chunk.id);
  130.                  fprintf(stderr," = ");
  131.                  IFF_Print_ID(stderr,formtype);
  132.                  fprintf(stderr,"\n");
  133.                 }
  134.         break;
  135.     case BMHD:
  136.         /* read Bit_Map_Header into bmhd */
  137.         /* read so as to avoid endian problems */
  138.         bmhd.width         = IFF_Get_HalfWord(fin);
  139.         bmhd.height         = IFF_Get_HalfWord(fin);
  140.         bmhd.x             = IFF_Get_HalfWord(fin);
  141.         bmhd.y             = IFF_Get_HalfWord(fin);
  142.         bmhd.depth        = fgetc(fin);
  143.         bmhd.masking              = fgetc(fin);
  144.         bmhd.compression          = fgetc(fin);
  145.         bmhd.pad1                 = fgetc(fin);
  146.         bmhd.transparentColor     = IFF_Get_HalfWord(fin);
  147.         bmhd.xAspect              = fgetc(fin);
  148.         bmhd.yAspect              = fgetc(fin);
  149.         bmhd.pageWidth             = IFF_Get_HalfWord(fin);
  150.         bmhd.pageHeight            = IFF_Get_HalfWord(fin);
  151.         if (verbose)
  152.         {
  153.                  fprintf(stderr,"     Size %ldx%ldx%ld comp=%ld masking=%ld\n",
  154.               bmhd.width,bmhd.height,bmhd.depth,bmhd.compression,bmhd.masking);
  155.         }
  156.         imagex = bmhd.width;
  157.         imagey = bmhd.height;
  158.         imaged = bmhd.depth;
  159.         if (imagex > iff_imagex) iff_imagex = imagex;
  160.         if (imagey > iff_imagey) iff_imagey = imagey;
  161.         bmhd_flag=1;
  162.         break;
  163.     case FACE:
  164.         /* read Face_Header into face */
  165.         /* read so as to avoid endian problems */
  166.         face.width         = IFF_Get_HalfWord(fin);
  167.         face.height         = IFF_Get_HalfWord(fin);
  168.         face.x             = IFF_Get_HalfWord(fin);
  169.         face.y             = IFF_Get_HalfWord(fin);
  170.         face.xoff         = IFF_Get_HalfWord(fin);
  171.         face.yoff        = IFF_Get_HalfWord(fin);
  172.         if (verbose)
  173.         {
  174.                  fprintf(stderr,"     Size %ldx%ld %ldx%ld %ldx%ld\n",
  175.                                   face.width,face.height,
  176.                                   face.x,face.y,face.xoff,face.yoff );
  177.         }
  178.         imagex = face.width;
  179.         imagey = face.height;
  180.         if (imagex > iff_imagex) iff_imagex = imagex;
  181.         if (imagey > iff_imagey) iff_imagey = imagey;
  182.         switch(imagec)
  183.         {
  184.          case  2: imaged = 1; break;
  185.          case  4: imaged = 2; break;
  186.          case  8: imaged = 3; break;
  187.          case 16: imaged = 4; break;
  188.          case 32: imaged = 5; break;
  189.          case 64: imaged = 6; break;
  190.                  default: 
  191.               fprintf(stderr,"IFF Face error imagec=%ld \n",imagec);
  192.               fprintf(stderr,"         camg_flag=%ld \n",camg_flag);
  193.               fprintf(stderr,"         cmap_flag=%ld \n",cmap_flag);
  194.               TheEnd();
  195.         }
  196.         bmhd.width       = imagex;
  197.         bmhd.height      = imagey;
  198.         bmhd.depth       = imaged;
  199.         bmhd.compression = BMHD_COMP_BYTERUN;
  200.         bmhd.masking     = BMHD_MSK_NONE;
  201.  
  202.                 action[action_cnt].data =
  203.                                 (BYTE *) malloc( sizeof(SIZE_HDR) );
  204.                 if (action[action_cnt].data == 0)
  205.                                 TheEnd1("IFF_Read_FACE: malloc failed\n");
  206.                 action[action_cnt].type = ACT_SIZE;
  207.                 action[action_cnt].time = 0;
  208.         { 
  209.          SIZE_HDR *size_hdr;
  210.          size_hdr = (SIZE_HDR *)action[action_cnt].data;
  211.          size_hdr->imagex = imagex;
  212.          size_hdr->imagey = imagey;
  213.          size_hdr->xoff = face.x + face.xoff;
  214.          size_hdr->yoff = face.y + face.yoff;
  215.         } 
  216.                 action_cnt++;
  217.         break;
  218.     case CAMG:
  219.            {
  220.         CMAP_HDR *cmap_hdr;
  221.  
  222.         cmap_hdr = (CMAP_HDR *)action[cmap_action].data;
  223.         if (debug_flag) fprintf(stderr,"IFF CAMG\n");
  224.         if (chunk.size == 4) 
  225.         {
  226.          camg_flag = IFF_Get_Word(fin);
  227.          if ((camg_flag & 0x80) && (cmap_flag))  
  228.                  {
  229.           IFF_Adjust_For_EHB( cmap_hdr->data );
  230.           cmap_hdr->cmap_size = imagec;
  231.           memcpy( (void *)cmap,
  232.               (void *)cmap_hdr->data,
  233.                           (x11_cmap_size * sizeof(ColorReg)) );
  234.                   break;
  235.                  }
  236.          if ((camg_flag & 0x800) && (cmap_flag)) 
  237.          {
  238.           ColorReg *hptr;
  239.           LONG i; 
  240.  
  241.           IFF_Adjust_For_HAM( cmap_hdr->data );
  242.           cmap_hdr->cmap_size = imagec;
  243.           anim_flags |= ANIM_HAM;
  244.             /* CREATE ACT_IFF_HMAP chunk */
  245.           action[action_cnt].data = 
  246.                 (BYTE *) malloc(HMAP_SIZE * sizeof(ColorReg) );
  247.           if (action[action_cnt].data == 0) 
  248.                 TheEnd1("IFF_Read_HMAP: malloc failed\n");
  249.           action[action_cnt].type = ACT_IFF_HMAP;
  250.           action[action_cnt].time = 0;
  251.           hptr = (ColorReg *)action[action_cnt].data;
  252.           for(i=0;i<HMAP_SIZE;i++) 
  253.           {
  254.            hptr[i].red   = ham_map[i].red;
  255.            hptr[i].green = ham_map[i].green;
  256.            hptr[i].blue  = ham_map[i].blue;
  257.           }
  258.           action_cnt++;
  259.           memcpy( (void *)cmap,
  260.               (void *)cmap_hdr->data,
  261.                           (x11_cmap_size * sizeof(ColorReg)) );
  262.                   break;
  263.          }
  264.         }
  265.         else ret = IFF_Read_Garb(fin,chunk.size);
  266.            }
  267.         break;
  268.     case CMAP:
  269.           {
  270.         CMAP_HDR *cmap_hdr;
  271.  
  272.         if (debug_flag) fprintf(stderr,"IFF CMAP\n");
  273.  
  274.         if (chunk.size == 0x40) imagec = chunk.size/2; /* R+GB */
  275.         else imagec = chunk.size / 3;  /* R+G+B 1 byte each */
  276.  
  277.         cmap_hdr = (CMAP_HDR *)
  278.                    malloc( x11_cmap_size * sizeof(ColorReg) + sizeof(CMAP_HDR));
  279.         if (cmap_hdr == 0) TheEnd1("IFF_Read_CMAP: malloc failed\n");
  280.         action[cmap_action].data = (char *)cmap_hdr;
  281.          cmap_hdr->cmap_size = imagec;
  282.  
  283.         if (chunk.size == 0x40)
  284.         {
  285.          LONG i,d;
  286.          for(i=0;i<imagec;i++)
  287.          {
  288.           d = fgetc(fin);
  289.           cmap[i].red   = (d<<4) & 0xf0;
  290.           d = fgetc(fin);
  291.           cmap[i].green =  d     & 0xf0;
  292.           cmap[i].blue  = (d<<4) & 0xf0;
  293.          }
  294.         }
  295.         else 
  296.         {
  297.          LONG i;
  298.          for(i=0;i<imagec;i++)
  299.          {
  300.           cmap[i].red   = fgetc(fin) & 0xf0;
  301.           cmap[i].green = fgetc(fin) & 0xf0;
  302.           cmap[i].blue  = fgetc(fin) & 0xf0;
  303.          }
  304.         }
  305.  
  306.         /* Typically imaged matches imagec but not always */
  307.         if (bmhd_flag)
  308.         {
  309.          switch(imaged)
  310.          {
  311.           case  1: imagec =   2; break;
  312.           case  2: imagec =   4; break;
  313.           case  3: imagec =   8; break;
  314.           case  4: imagec =  16; break;
  315.           case  5: imagec =  32; break;
  316.           case  6: imagec =  64; break;
  317.           case  7: imagec = 128; break;
  318.           case  8: imagec = 256; break;
  319.          }
  320.         }
  321.  
  322.         if (camg_flag & 0x80)  IFF_Adjust_For_EHB(cmap);
  323.         if (camg_flag & 0x800) 
  324.         {
  325.          ColorReg *hptr;
  326.          LONG i; 
  327.          IFF_Adjust_For_HAM(cmap);
  328.          anim_flags |= ANIM_HAM;
  329.             /* CREATE ACT_IFF_HMAP chunk */
  330.           action[action_cnt].data = 
  331.                 (BYTE *) malloc(HMAP_SIZE * sizeof(ColorReg) );
  332.           if (action[action_cnt].data == 0) 
  333.                 TheEnd1("IFF_Read_HMAP: malloc failed\n");
  334.           action[action_cnt].type = ACT_IFF_HMAP;
  335.           action[action_cnt].time = 0;
  336.           hptr = (ColorReg *)action[action_cnt].data;
  337.           for(i=0;i<HMAP_SIZE;i++) 
  338.           {
  339.            hptr[i].red   = ham_map[i].red;
  340.            hptr[i].green = ham_map[i].green;
  341.            hptr[i].blue  = ham_map[i].blue;
  342.           }
  343.           action_cnt++;
  344.  
  345.         }
  346.          cmap_hdr->cmap_size = imagec;
  347.         memcpy( (void *)cmap_hdr->data,
  348.             (void *)cmap,
  349.             (x11_cmap_size * sizeof(ColorReg)) );
  350.         cmap_flag = 1;
  351.  
  352.           }
  353.         break;
  354.     case BODY:
  355.         if (debug_flag) fprintf(stderr,"IFF BODY\n");
  356.         dlta_cnt++;
  357.         if (body_1 == -1) body_1 = action_cnt;
  358.         action[action_cnt].data = 
  359.                 (BYTE *) malloc( imagex * imagey );
  360.         if (action[action_cnt].data == 0) 
  361.                 TheEnd1("IFF_Read_BODY: malloc failed\n");
  362.         action[action_cnt].type = ACT_IFF_BODY;
  363.         if (jiffy_flag) action[action_cnt].time = jiffy_flag;
  364.         else action[action_cnt].time = 
  365.             IFF_SPEED_DEFAULT * MS_PER_60HZ;
  366.  
  367.         IFF_Read_BODY(fin,action[action_cnt].data,chunk.size,
  368.                 (int)(bmhd.compression),(int)(bmhd.masking));
  369.         action_cnt++;
  370.         break;
  371.  
  372.     case ANHD:
  373.         {
  374.          if (debug_flag) fprintf(stderr,"IFF ANHD\n");
  375.  
  376.          if (chunk.size == Anim_Header_SIZE)
  377.          {
  378.           anhd.op         = fgetc(fin);
  379.           anhd.mask         = fgetc(fin);
  380.           anhd.w         = IFF_Get_HalfWord(fin);
  381.           anhd.h         = IFF_Get_HalfWord(fin);
  382.           anhd.x         = IFF_Get_HalfWord(fin);
  383.           anhd.y         = IFF_Get_HalfWord(fin);
  384.           anhd.abstime         = IFF_Get_Word(fin);
  385.           anhd.reltime         = IFF_Get_Word(fin);
  386.           anhd.interleave     = fgetc(fin);
  387.           anhd.pad0         = fgetc(fin);
  388.           anhd.bits        = IFF_Get_Word(fin);
  389.           fread((BYTE *)(anhd.pad),1,16,fin); /* read pad */
  390.  
  391.           compression = anhd.op;
  392.          }
  393.          else 
  394.          {
  395.           IFF_Read_Garb(fin,chunk.size); 
  396.           compression = 0xffffffff;
  397.           fprintf(stderr,"ANHD chunksize mismatch %ld\n",chunk.size);
  398.          }
  399.         }
  400.         break;
  401.  
  402.     case DLTA:
  403.         {
  404.          ACT_IFF_DLTA_HDR *dlta_hdr;
  405.          if (debug_flag) fprintf(stderr,"IFF DLTA: ");
  406.          dlta_cnt++;
  407.              if (dlta_2 == -1) dlta_2 = action_cnt; /* 2nd DLTA */
  408.          if (dlta_2 == -2) dlta_2 = -1;  /* 1st DLTA */
  409.          dlta_hdr = (ACT_IFF_DLTA_HDR *)
  410.             (BYTE *)malloc(sizeof(ACT_IFF_DLTA_HDR) + chunk.size);
  411.                  if (dlta_hdr == 0) TheEnd1("IFF_Read_DLTA: malloc failed");
  412.                  action[action_cnt].data = (BYTE *)(dlta_hdr);
  413.                  ret=fread(dlta_hdr->data,chunk.size,1,fin);
  414.  
  415.          switch(compression)
  416.          {
  417.           case 5:
  418.              if (debug_flag) fprintf(stderr,"type 5\n");
  419.              action[action_cnt].type = ACT_IFF_DLTA5;
  420.               break;
  421.           case   3:
  422.              if (debug_flag) fprintf(stderr,"type 3\n");
  423.              action[action_cnt].type = ACT_IFF_DLTA3;
  424.               break;
  425.           case 'J':
  426.              if (debug_flag) fprintf(stderr,"type J\n");
  427.              action[action_cnt].type = ACT_IFF_DLTAJ;
  428.               break;
  429.           case  108:
  430.              if (debug_flag) fprintf(stderr,"type l\n");
  431.              action[action_cnt].type = ACT_IFF_DLTAl;
  432.               break;
  433.           case   0:
  434.           case   1:
  435.           case   2:
  436.           case   4:
  437.           default:  
  438.              action[action_cnt].type = ACT_NOP;
  439.              fprintf(stderr,"Unimplemented Delta %ld\n",compression);
  440.               break;
  441.          }
  442.          if (jiffy_flag) action[action_cnt].time = jiffy_flag;
  443.          else action[action_cnt].time = 
  444.             IFF_SPEED_DEFAULT * MS_PER_60HZ;
  445.          action_cnt++;
  446.         }
  447.         break;
  448.  
  449.     case ANSQ:
  450.         if (debug_flag) fprintf(stderr,"IFF ANSQ\n");
  451.                {
  452.                 ULONG i;
  453.                 UBYTE *p;  /* data is actually big endian USHORT */
  454.                 BYTE *garb;
  455.  
  456.                 ansq_flag = 1;  /* we found an ansq chunk */
  457.                 ansq_cnt = chunk.size / 4;
  458.                 ansq_cnt = ansq_cnt + 1; /* adding dlta 0 up front */
  459.  
  460.         if (debug_flag) fprintf(stderr,
  461.         "    ansq_cnt=%ld dlta_cnt=%ld\n",ansq_cnt,dlta_cnt);
  462.  
  463.         /* allocate space for ansq variables 
  464.          */
  465.                 ansq_dnum = (LONG *)malloc( ansq_cnt * sizeof(LONG));
  466.                 ansq_tim  = (LONG *)malloc( ansq_cnt * sizeof(LONG));
  467.         if ( (ansq_dnum==NULL) || (ansq_tim==NULL)) 
  468.             TheEnd1("ansq can't malloc dnum and tim arrays\0");
  469.                 if (verbose) fprintf(stderr,
  470.             "     frames=%ld dlts=%d comp=%ld\n",
  471.                 ansq_cnt,dlta_cnt,compression);
  472.  
  473.                 garb = (BYTE *)malloc(chunk.size);
  474.                 if (garb==0)
  475.                       {fprintf(stderr,"ansq malloc not enough\n"); TheEnd();}
  476.                 fread(garb,chunk.size,1,fin);
  477.                 p = (UBYTE *)(garb);
  478.  
  479.         /* first delta is only used once and doesn't appear in 
  480.          * the ANSQ 
  481.          */
  482.                 ansq_dnum[0] = 0; 
  483.                 ansq_tim[0]  = 1;
  484.                 for(i=1;i<ansq_cnt;i++)
  485.                 {
  486.                   /* this is delta to apply */
  487.                   ansq_dnum[i] = (*p++)<<8; ansq_dnum[i] |= (*p++);
  488.  
  489.                   /* this is jiffy count or if 0xffff then a goto */
  490.                   ansq_tim[i] = (*p++)<<8;  ansq_tim[i] |= (*p++);
  491.  
  492.           if (debug_flag) fprintf(stderr,"<%ld %ld> ",ansq_dnum[i],
  493.                         ansq_tim[i]);
  494.                 }
  495.                 free(garb);
  496.                }
  497.                break;
  498.  
  499.     case CRNG: 
  500.         if (debug_flag) fprintf(stderr,"IFF CRNG\n");
  501.         {
  502.          CRNG_HDR *crng_ptr;
  503.  
  504.          /* is the chunk the correct size ?
  505.           */
  506.          if (chunk.size == CRNG_HDR_SIZE)
  507.          {
  508.            /* allocate space and read CRNG chunk 
  509.             */
  510.                    crng_ptr = (CRNG_HDR *)malloc( sizeof(CRNG_HDR) );
  511.                    if (crng_ptr == 0) 
  512.                  TheEnd1("IFF_Read_CRNG: malloc failed");
  513.            action[action_cnt].data = (BYTE *) crng_ptr;
  514.            crng_ptr->pad1   = IFF_Get_HalfWord(fin);
  515.            crng_ptr->rate   = IFF_Get_HalfWord(fin);
  516.            crng_ptr->active = IFF_Get_HalfWord(fin);
  517.            crng_ptr->low    = fgetc(fin);
  518.            crng_ptr->high   = fgetc(fin);
  519.  
  520.            /* make it an action only if its valid 
  521.             */
  522.                    if (   (crng_ptr->active & CRNG_ACTIVE)
  523.                        && (crng_ptr->low < crng_ptr->high)
  524.                        && (crng_ptr->rate != 0)
  525.                   )
  526.            {
  527.              crng_flag++;
  528.              action[action_cnt].type = ACT_IFF_CRNG;
  529.              action[action_cnt].time = 0;
  530.              action_cnt++;
  531.            }
  532.            else 
  533.            {
  534.              free(crng_ptr);
  535.              if (debug_flag) fprintf(stderr,"CRNG not used\n");
  536.            }
  537.          }
  538.          else
  539.          {
  540.             IFF_Read_Garb(fin,chunk.size); 
  541.             fprintf(stderr,"CRNG chunksize mismatch %ld\n",chunk.size);
  542.          }
  543.         }
  544.         break;
  545.  
  546.     case GRAB: /* ignore */
  547.     case DPPS: /* ignore */
  548.     case DPPV: /* ignore */
  549.     case DPAN: /* ignore */
  550.     case VHDR: /* sound ignore should kill next body until bmhd*/
  551.     case ANNO: /* sound ignore */
  552.     case CHAN: /* sound ignore */
  553.                 ret = IFF_Read_Garb(fin,chunk.size);
  554.                 break;
  555.     default:
  556.             if ( !feof(fin) ) /* if not at end of file */
  557.            {
  558.                 fprintf(stderr,"unknown IFF type=");
  559.                 IFF_Print_ID(stderr,chunk.id);
  560.                 fprintf(stderr,"\n");
  561.            }
  562.            exit_flag = 1;
  563.                break;
  564.    } /* end chunk switch */
  565.   } /* end if ret==0 */
  566.  } /* end of while not eof or exit_flag */
  567.  fclose(fin);
  568.  
  569.  if (ansq_flag)
  570.  {
  571.    LONG i;
  572.  
  573.    /* 
  574.     * Set up a map of delta's to their action numbers.
  575.     */
  576.    dlta_act = (LONG *)malloc( sizeof(int) * dlta_cnt );
  577.    j=0;
  578.    for(i=action_start; i < action_cnt; i++)
  579.    {
  580.     switch(action[i].type)
  581.     {
  582.      case ACT_IFF_BODY:
  583.      case ACT_IFF_DLTA1:
  584.      case ACT_IFF_DLTA2:
  585.      case ACT_IFF_DLTA3:
  586.      case ACT_IFF_DLTA4:
  587.      case ACT_IFF_DLTA5:
  588.      case ACT_IFF_DLTAJ:
  589.                dlta_act[j] = i; j++;
  590.                break;
  591.     }
  592.    }
  593.    if (debug_flag) fprintf(stderr,"%ld dltas found\n",j);
  594.    /* NOTE: since we're treating the BODY as a delta, the ansq's will be
  595.     *   one off 
  596.     */
  597.  
  598.    /* +2 is for cmap up front and frame termination at end */
  599.    anim[anim_cnt].frame_lst = (LONG *)malloc(sizeof(int) * (ansq_cnt+2));
  600.    if (anim[anim_cnt].frame_lst == NULL) 
  601.              TheEnd1("IFF ANSQ: couldn't malloc for frame_lst\0");
  602.  
  603.        /* loop frame is the 2nd delta */
  604.         anim[anim_cnt].loop_frame = body_1 - action_start;
  605.    anim[anim_cnt].loop_frame = dlta_2 - action_start;  
  606.    anim[anim_cnt].frame_lst[0] = cmap_action;  /* cmap action */
  607.    j=1;
  608.    for(i=action_start; i<= body_1; i++)
  609.    {
  610.     anim[anim_cnt].frame_lst[j] = i;  /* take care of frame up to body_1 */
  611.     j++;
  612.    }
  613.     
  614.    for(i=0;i<ansq_cnt;i++)
  615.    {
  616.      /* Goto */
  617.      if (ansq_tim[i] == 0xffff)
  618.      {
  619.       anim[anim_cnt].loop_frame = j + ansq_dnum[i]; /* cmap, body */
  620. /* NOTE:
  621.       anim[anim_cnt].frame_lst[i+j] = -1;
  622. */
  623.      }
  624.      else /* delta to use */
  625.      {
  626.       anim[anim_cnt].frame_lst[i+j] = dlta_act[ ansq_dnum[i]+1 ];
  627.       /* the +1 below is because the ansq chunk ignores the body */
  628.       if (jiffy_flag) action[ dlta_act[ ansq_dnum[i]+1 ] ].time = jiffy_flag;
  629.       else action[ dlta_act[ ansq_dnum[i]+1 ] ].time = 
  630.             ansq_tim[i] * MS_PER_60HZ;
  631.      } 
  632.    } /* end of for ansq_cnt */
  633.    anim[anim_cnt].frame_lst[ansq_cnt+j] = -1;
  634.    anim[anim_cnt].last_frame = ansq_cnt + j - 1;
  635.   }
  636.    /* no ansq chunk */
  637.   else
  638.   {
  639.     LONG frame_num,ii;
  640.  
  641.     frame_num = action_cnt - action_start;
  642.     anim[anim_cnt].frame_lst = (LONG *)malloc(sizeof(int) * (frame_num+1));
  643.     if (anim[anim_cnt].frame_lst == NULL)
  644.              TheEnd1("IFF: couldn't malloc for frame_lst\0");
  645.     for(ii=0; ii < frame_num; ii++)
  646.            anim[anim_cnt].frame_lst[ii]=action_start+ii;
  647.  
  648.     /* loop frame is the 2nd delta or 1st body if not two deltas 
  649.      * or if ANIM_NOLOP set
  650.      */
  651.     if ( (dlta_2 < 0) || (anim_flags & ANIM_NOLOP) )
  652.         anim[anim_cnt].loop_frame = body_1 - action_start;
  653.     else 
  654.         anim[anim_cnt].loop_frame = dlta_2 - action_start;
  655.  
  656.     anim[anim_cnt].frame_lst[frame_num] = -1;
  657.     anim[anim_cnt].last_frame = frame_num - 1;
  658.     if (verbose) fprintf(stderr,"     dlta_cnt=%ld comp=%ld\n",
  659.                              dlta_cnt,compression);
  660.   }
  661.  
  662.   if (ansq_dnum) free(ansq_dnum); 
  663.   if (ansq_tim ) free(ansq_tim ); 
  664.   if (dlta_act ) free(dlta_act ); 
  665.   imagex = iff_imagex;
  666.   imagey = iff_imagey;
  667.  
  668.   if ( (dlta_cnt == 1) && (crng_flag) ) anim_flags |= ANIM_CYCLE;
  669.   else anim_flags &= (~ANIM_CYCLE);
  670. }
  671.  
  672.  
  673. /*
  674.  *
  675.  */
  676. void IFF_Adjust_For_EHB(colormap)
  677. ColorReg colormap[];
  678. {
  679.  LONG i;
  680.  if (verbose) fprintf(stderr,"Adjusting CMAP for Amiga Extra Half-Brite Mode\n");
  681.  for(i=0;i<32;i++)
  682.  {
  683.   colormap[i+32].red   = colormap[i].red   >> 2;
  684.   colormap[i+32].green = colormap[i].green >> 2;
  685.   colormap[i+32].blue  = colormap[i].blue  >> 2;
  686.  }
  687.  imagec = 64;
  688. }
  689.  
  690.  
  691. /*
  692.  *
  693.  */
  694. void IFF_Adjust_For_HAM(colormap)
  695. ColorReg colormap[];
  696. {
  697.  LONG i;
  698.  if (verbose) fprintf(stderr,"Adjusting CMAP for Amiga Hold And Modify Mode\n");
  699.  
  700.  /* save original color registers - will be need later */
  701.  for(i=0;i<HMAP_SIZE;i++)
  702.  {
  703.   ham_map[i].red   = (colormap[i].red   >> 4) & 0x0f;
  704.   ham_map[i].green = (colormap[i].green >> 4) & 0x0f;
  705.   ham_map[i].blue  = (colormap[i].blue  >> 4) & 0x0f;
  706.  }
  707.  /* generate kludged color map */
  708.  /* basically 3 bits red, 3 bits green and 2 bits blue */
  709.  for(i=0;i<256;i++)
  710.  {
  711.   colormap[i].red   = ((i>>5) & 0x07) * 36;
  712.   colormap[i].green = ((i>>2) & 0x07) * 36;
  713.   colormap[i].blue  = (i & 0x03) * 84;
  714.  }
  715.  imagec = 256;
  716. }
  717.  
  718.  
  719. /*
  720.  *
  721.  */
  722. void IFF_Read_BODY(fin,image_out,bodysize,compression,masking)
  723. FILE *fin;
  724. UBYTE *image_out;
  725. LONG bodysize,compression,masking;
  726. {
  727.  LONG i,ret,x,y,d,dmask,tmp,rowsize;
  728.  LONG imagex_pad;
  729.  BYTE *inbuff,*rowbuff,*sptr;
  730.  BYTE *sbuff,*dbuff;
  731.  
  732.  if (   (compression != BMHD_COMP_NONE) 
  733.      && (compression != BMHD_COMP_BYTERUN) 
  734.     ) TheEnd1("IFF_Read_Body: unsupported compression");
  735.  
  736.  if (   (masking != BMHD_MSK_NONE)
  737.      && (masking != BMHD_MSK_HAS)
  738.      && (masking != BMHD_MSK_TRANS)
  739.     ) TheEnd1("IFF_Read_Body: unsupported masking");
  740.  
  741.  inbuff = (BYTE *)malloc(bodysize);
  742.  if (inbuff == 0) TheEnd1("IFF_Read_Body: malloc failed");
  743.  ret=fread(inbuff,bodysize,1,fin);
  744.  if (ret!=1) TheEnd1("IFF_Read_Body: read of BODY chunk failed");
  745.  sbuff = inbuff;
  746.  
  747.  rowbuff = (BYTE *)malloc( imagex );
  748.  if (rowbuff == 0) TheEnd1("IFF_Read_Body: malloc failed");
  749.  
  750.  i =  (1 << imaged) - 1;
  751.  dmask = ~i;
  752.  memset(image_out,dmask & 0xff,(imagex * imagey));
  753.  dmask = 1;
  754.  
  755.  if (compression==BMHD_COMP_NONE) sptr = inbuff;
  756.  
  757.  /* width is rounded to multiples of 16 in the BODY form */
  758.  /* extra bits are ignored upon reading */
  759.  imagex_pad = imagex % 16;
  760.  if (imagex_pad) imagex_pad = imagex + 16 - imagex_pad;
  761.  else imagex_pad = imagex;
  762.  
  763.  for(y=0; y<imagey; y++)
  764.  {
  765.   tmp = y * imagex;
  766.   dmask=1;
  767.   for(d=0; d<imaged; d++)
  768.   {
  769.  
  770.    if (compression == BMHD_COMP_BYTERUN)
  771.    {
  772. /* Question */
  773. /* imagex_pad OR imagex. Need compressed file the is not a multipleof 16 */
  774.     rowsize = imagex_pad / 8; 
  775.  
  776.     dbuff = rowbuff;
  777.     ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  778.     if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); TheEnd();}
  779.     sptr = rowbuff;
  780.    }
  781.  
  782.    for(x=0; x<imagex; x+=8)
  783.    {
  784.     for(i=0; i<8; i++) if (mask[i] & (*sptr)) image_out[tmp+x+i] |= dmask;
  785.     sptr++;
  786.    }
  787.    if (imagex_pad >= (imagex+8)) sptr++;
  788.  
  789.    dmask <<= 1;
  790.   } /* end of depth loop */
  791.  
  792.   if (masking == BMHD_MSK_HAS)
  793.   {
  794.    /* read the mask row and then throw out for now */
  795.    if (compression == BMHD_COMP_BYTERUN)
  796.    {
  797.     rowsize = imagex_pad / 8;
  798.     dbuff = rowbuff;
  799.     ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  800.     if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); TheEnd();}
  801.    }
  802.    else sptr += imagex/8;
  803.   }
  804.  } /* end of y loop */
  805.  free(inbuff);
  806.  free(rowbuff);
  807. }
  808.  
  809.  
  810. /*
  811.  *
  812.  */
  813. LONG IFF_Read_Garb(fp,size)
  814. FILE *fp;
  815. LONG size;
  816. {
  817.  BYTE *garb;
  818.  
  819.  garb = (BYTE *)malloc(size);
  820.  if (garb==0)
  821.  { fprintf(stderr,"readgarb malloc err size=%ld",size); return(-1);}
  822.  fread(garb,size,1,fp);
  823.  free(garb);
  824.  return(0);
  825. }
  826.  
  827. void IFF_Print_ID(fout,id)
  828. FILE *fout;
  829. LONG id;
  830. {
  831.  fprintf(fout,"%c",     ((id >> 24) & 0xff)   );
  832.  fprintf(fout,"%c",     ((id >> 16) & 0xff)   );
  833.  fprintf(fout,"%c",     ((id >>  8) & 0xff)   );
  834.  fprintf(fout,"%c(%lx)", (id        & 0xff),id);
  835. }
  836.  
  837.  
  838. /* 
  839.  *
  840.  */
  841. void IFF_Delta5(fptr,deltaptr,r_hdr)
  842. UBYTE *fptr;
  843. UBYTE *deltaptr;
  844. ACT_IFF_DLTA_HDR *r_hdr;
  845. {
  846.  register LONG i,col,depth,dmask;
  847.  register LONG rowsize,width;
  848.  ULONG poff;
  849.  register UBYTE *imageptr;
  850.  register UBYTE *dptr,opcnt,op,cnt,data;
  851.  LONG miny,minx,maxy,maxx;
  852.  
  853.  r_hdr->minx  = imagex;
  854.  r_hdr->miny  = imagey;
  855.  r_hdr->maxx = 0;
  856.  r_hdr->maxy = 0;
  857.  
  858.  imageptr = fptr;
  859.  width = imagex;
  860.  rowsize = width / 8;
  861.  dmask = 1;
  862.  for(depth=0; depth<imaged; depth++)
  863.  {
  864.   minx = -1;
  865.   maxx = -1;
  866.   
  867.   imageptr = fptr;
  868.   /* offset into delt chunk */
  869.   poff  = (deltaptr[ 4 * depth    ]) << 24;
  870.   poff |= (deltaptr[ 4 * depth + 1]) << 16;
  871.   poff |= (deltaptr[ 4 * depth + 2]) <<  8;
  872.   poff |= (deltaptr[ 4 * depth + 3]);
  873.  
  874.   if (poff)
  875.   {
  876.    dptr = (UBYTE *)((ULONG)(deltaptr) + poff);
  877.    for(col=0;col<rowsize;col++)
  878.    {
  879.     imageptr = (UBYTE *)((ULONG)(fptr) + col * 8); /* start at top of column */
  880.     opcnt = *dptr++;  /* get number of ops for this column */
  881.     
  882.     miny = -1;
  883.     maxy = -1;
  884.  
  885.     while(opcnt)    /* execute ops */
  886.     {
  887.        /* keep track of min and max columns */
  888.        if (minx == -1) minx = col * 8;
  889.        maxx = (col * 8) + 7;  
  890.  
  891.        op = *dptr++;   /* get op */
  892.      
  893.        if (op & 0x80)    /* if type uniqe */
  894.        {
  895.           if (miny == -1) miny=( (ULONG)imageptr - (ULONG)fptr ) / width;
  896.           cnt = op & 0x7f;         /* get cnt */
  897.       
  898.           for(i=0;i<cnt;i++)       /* loop through data */
  899.           {
  900.              data = *dptr++;
  901.              IFF_Byte_Mod(imageptr,data,dmask,0);
  902.              imageptr += width;
  903.           }
  904.         } /* end unique */
  905.         else
  906.         {
  907.            if (op == 0)   /* type same */
  908.            {
  909.               if (miny == -1) miny=( (ULONG)imageptr - (ULONG)fptr ) / width;
  910.               cnt = *dptr++;
  911.               data = *dptr++;
  912.  
  913.               for(i=0;i<cnt;i++)       /* loop through data */
  914.               { 
  915.                  IFF_Byte_Mod(imageptr,data,dmask,0);
  916.                  imageptr += width;
  917.               }
  918.             } /* end same */
  919.             else
  920.             {
  921.                imageptr += (width * op);  /* type skip */
  922.             }
  923.          } /* end of hi bit clear */
  924.        opcnt--;
  925.      } /* end of while opcnt */
  926.      maxy = ( (ULONG)imageptr -(ULONG)fptr ) / width;
  927.      if ( (miny>=0) && (miny < r_hdr->miny)) r_hdr->miny = miny;
  928.      if ( (maxy>=0) && (maxy > r_hdr->maxy)) r_hdr->maxy = maxy;
  929.     } /* end of column loop */
  930.    } /* end of valid pointer for this plane */
  931.    dmask <<= 1;
  932.    if ( (minx>=0) && (minx < r_hdr->minx)) r_hdr->minx = minx;
  933.    if ( (maxx>=0) && (maxx > r_hdr->maxx)) r_hdr->maxx = maxx;
  934.   } /* end of for depth */
  935.  
  936.   if (r_hdr->minx >= imagex) r_hdr->minx = 0;
  937.   if (r_hdr->miny >= imagey) r_hdr->miny = 0;
  938.   if (r_hdr->maxx <= 0)      r_hdr->maxx = imagex;
  939.   if (r_hdr->maxy <= 0)      r_hdr->maxy = imagey;
  940.  
  941. } /* end of routine */
  942.  
  943. /*
  944.  * 
  945.  */
  946. void IFF_Delta3(fptr,deltaptr)
  947. UBYTE *fptr;
  948. UBYTE *deltaptr;
  949. {
  950.  register LONG i,depth,dmask;
  951.  ULONG poff;
  952.  register SHORT  offset;
  953.  register USHORT s,data;
  954.  register UBYTE  *imageptr,*dptr;
  955.  
  956.  imageptr = fptr;
  957.  dmask = 1;
  958.  for(depth=0;depth<imaged;depth++)
  959.  {
  960.   imageptr = fptr;
  961.  
  962.   /*poff = planeoff[depth];*/ /* offset into delt chunk */
  963.  
  964.   poff  = (deltaptr[ 4 * depth    ]) << 24;
  965.   poff |= (deltaptr[ 4 * depth + 1]) << 16;
  966.   poff |= (deltaptr[ 4 * depth + 2]) <<  8;
  967.   poff |= (deltaptr[ 4 * depth + 3]);
  968.  
  969.   if (poff)
  970.   {
  971.    dptr = (UBYTE *)( (ULONG)(deltaptr) + poff);
  972.    while( (dptr[0] != 0xff) || (dptr[1] != 0xff) )
  973.    {
  974.      offset = (*dptr++)<<8; offset |= (*dptr++);
  975.      if (offset >= 0)
  976.      {
  977.       data = (*dptr++)<<8; data |= (*dptr++);
  978.       imageptr += 16 * (ULONG)(offset);
  979.       IFF_Short_Mod(imageptr,data,dmask,0);
  980.      } /* end of pos */
  981.      else
  982.      {
  983.       imageptr += 16 * (ULONG)(-(offset+2));
  984.       s = (*dptr++)<<8; s |= (*dptr++); /* size of next */
  985.       for(i=0; i < (ULONG)s; i++)
  986.       {
  987.        data = (*dptr++)<<8; data |= (*dptr++);
  988.        imageptr += 16;
  989.        IFF_Short_Mod(imageptr,data,dmask,0);
  990.       }
  991.     }  /* end of neg */
  992.    } /* end of delta for this plane */
  993.   } /* plane has changed data */
  994.   dmask <<= 1;
  995.  } /* end of d */
  996. }
  997.  
  998. /* 
  999.  *
  1000.  */
  1001. void IFF_Byte_Mod(iptr,data,dmask,xorflag)
  1002. register BYTE *iptr;
  1003. register UBYTE data;
  1004. ULONG dmask;
  1005. register ULONG xorflag;
  1006. {
  1007.  register LONG i,rmask;
  1008.  register UBYTE dmskoff,dmskon;
  1009.  
  1010.  dmskon = dmask;
  1011.  dmskoff = ~dmask;
  1012.  rmask = 0x80;
  1013.  if (xorflag)
  1014.  {
  1015.     /* if set then invert bit */
  1016.  
  1017.   for(i=0;i<8;i++)
  1018.   {
  1019.    if (rmask & data) *iptr++ ^= dmskon; /* invert bit */
  1020.    else iptr++;   /* do nothing but still have to inc ptr */
  1021.    rmask >>= 1;
  1022.   }
  1023.  }
  1024.  else
  1025.  {
  1026.     /* if set then set bit otherwise clear */
  1027.   for(i=0;i<8;i++)
  1028.   {
  1029.    if (rmask & data) *iptr++ |= dmskon;
  1030.    else *iptr++ &= dmskoff;
  1031.    rmask >>= 1;
  1032.   }
  1033.  }
  1034. }
  1035.  
  1036.  
  1037. /* 
  1038.  *
  1039.  */
  1040. void IFF_Short_Mod(iptr,data,dmask,xorflag)
  1041. UBYTE *iptr;
  1042. USHORT data;
  1043. ULONG dmask;
  1044. LONG xorflag;
  1045. {
  1046.  register LONG i;
  1047.  register UBYTE bdata,dmskoff,dmskon;
  1048.  
  1049.  dmskon = dmask;
  1050.  dmskoff = ~dmask;
  1051.  if (xorflag)
  1052.  {
  1053.   bdata = (UBYTE)(data >> 8);
  1054.   for(i=0;i<8;i++)
  1055.   {
  1056.    if (mask[i] & bdata) *iptr++ ^= dmskon;
  1057.    else iptr++;
  1058.   }
  1059.   bdata = (UBYTE)(data & 0xff);
  1060.   for(i=0;i<8;i++)
  1061.   {
  1062.    if (mask[i] & bdata) *iptr++ ^= dmskon;
  1063.    else iptr++;
  1064.   }
  1065.  }
  1066.  else
  1067.  {
  1068.   bdata = (UBYTE)(data >> 8);
  1069.   for(i=0;i<8;i++)
  1070.   {
  1071.    if (mask[i] & bdata) *iptr++ |= dmskon;
  1072.    else *iptr++ &= dmskoff;
  1073.   }
  1074.   bdata = (UBYTE)(data & 0xff);
  1075.   for(i=0;i<8;i++)
  1076.   {
  1077.    if (mask[i] & bdata) *iptr++ |= dmskon;
  1078.    else *iptr++ &= dmskoff;
  1079.   }
  1080.  }
  1081. }
  1082.  
  1083.  
  1084. /* 
  1085.  *
  1086.  */
  1087. void IFF_HAM_To_332(hptr,dptr)
  1088. register UBYTE *hptr;
  1089. register UBYTE *dptr;
  1090. {
  1091.  register LONG x,y;
  1092.  register LONG w,h;
  1093.  register ULONG pred;
  1094.  register ULONG pgreen;
  1095.  register ULONG pblue;
  1096.  register ULONG data;
  1097.  
  1098.  w = imagex;
  1099.  h = imagey;
  1100.  
  1101.  for (y=0; y<h; y++)
  1102.  {
  1103.   pred=pgreen=pblue=0;
  1104.   for (x=0; x<w; x++)
  1105.   {
  1106.    data = (ULONG )(*hptr++);
  1107.    switch( (data & 0x30) )
  1108.    {
  1109.     case 0x00: /* use color register given by low */
  1110.                 {
  1111.                  register ULONG low;
  1112.                  low = data & 0x0f;
  1113.                  pred   = ham_map[low].red;
  1114.                  pgreen = ham_map[low].green;
  1115.                  pblue  = ham_map[low].blue;
  1116.                 }
  1117.                 break;
  1118.     case 0x10: /* hold red and green   but change blue to low*/
  1119.                 pblue = data & 0x0f;
  1120.                 break;
  1121.     case 0x20: /* hold green and blue  but change red to low */
  1122.                 pred = data & 0x0f;
  1123.                 break;
  1124.     case 0x30: /* hold red and blue    but change green to low */
  1125.                 pgreen = data & 0x0f;
  1126.                 break;
  1127.    } /* end of switch */
  1128.    *dptr++ =   ((pred   & 0x0e) << 4)
  1129.              | ((pgreen & 0x0e) << 1)
  1130.              | ((pblue  & 0x0c) >> 2);
  1131.   } /* end of x */
  1132.  } /* end of y */
  1133. }
  1134.  
  1135.  
  1136. /* 
  1137.  *
  1138.  */
  1139. LONG Is_IFF_File(filename)
  1140. BYTE *filename;
  1141. {
  1142.  FILE *fp;
  1143.  ULONG firstword;
  1144.  
  1145.  if ( (fp=fopen(filename,"r")) == 0)
  1146.  { 
  1147.   fprintf(stderr,"can't open %s\n",filename); 
  1148.   TheEnd();
  1149.  }
  1150.   /* by reading bytes we can ignore big/little endian problems */
  1151.  firstword  = (fgetc(fp) & 0xff) << 24;
  1152.  firstword |= (fgetc(fp) & 0xff) << 16;
  1153.  firstword |= (fgetc(fp) & 0xff) <<  8;
  1154.  firstword |= (fgetc(fp) & 0xff);
  1155.  
  1156.  fclose(fp);
  1157.  
  1158.  if (firstword == FORM) return(TRUE);
  1159.  if (firstword == LIST) return(TRUE);
  1160.  if (firstword == PROP) return(TRUE);
  1161.  return(FALSE);
  1162. }
  1163.  
  1164.  
  1165. /* 
  1166.  *
  1167.  */
  1168. void IFF_Buffer_Action(action_start)
  1169. LONG action_start;
  1170. {
  1171.  LONG i,image_size;
  1172.  BYTE *buff0,*buff1,*tmp;
  1173.  ACTION *act;
  1174.  
  1175.  image_size = imagex * imagey;
  1176.  buff0 = (BYTE *) malloc( image_size );
  1177.  if (buff0 == 0) TheEnd1("IFFBufferAction: malloc failed");
  1178.  
  1179.  buff1 = (BYTE *) malloc( image_size );
  1180.  if (buff1 == 0) 
  1181.  {
  1182.   free(buff0);
  1183.   TheEnd1("IFFBufferAction: malloc failed");
  1184.  }
  1185.  
  1186.   old_dlta[0].minx = imagex; old_dlta[0].miny = imagey;
  1187.   old_dlta[0].maxx = 0;          old_dlta[0].maxy = 0;
  1188.   old_dlta[1].minx = imagex; old_dlta[1].miny = imagey;
  1189.   old_dlta[1].maxx = 0;          old_dlta[1].maxy = 0;
  1190.  
  1191.  i=action_start;
  1192.  while(i<action_cnt)
  1193.  {
  1194.   act = &action[i];
  1195.   switch(act->type)
  1196.   {
  1197.    case ACT_SIZE:    
  1198.             { 
  1199.              SIZE_HDR *size_hdr;
  1200.              size_hdr = (SIZE_HDR *)act->data;
  1201.              imagex = size_hdr->imagex;
  1202.              imagey = size_hdr->imagey;
  1203.             } 
  1204.             break;
  1205.    case ACT_IFF_BODY:    
  1206.             memcpy(buff0,act->data,image_size);
  1207.             memcpy(buff1,act->data,image_size);
  1208.             if (anim_flags & ANIM_HAM) 
  1209.                    IFF_HAM_To_332(buff0,act->data);
  1210.                act->type = ACT_IMAGE;
  1211.             break;
  1212.    case ACT_IFF_DLTA5:
  1213.             {
  1214.              ACT_IFF_DLTA_HDR *iff_dlta_hdr;
  1215.              ACT_REGION_HDR *region_hdr;
  1216.  
  1217.              iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
  1218.              IFF_Delta5(buff0,iff_dlta_hdr->data,iff_dlta_hdr);
  1219.  
  1220.              old_dlta[0].minx =
  1221.                                 MIN(old_dlta[0].minx,iff_dlta_hdr->minx);
  1222.                          old_dlta[0].miny =
  1223.                                 MIN(old_dlta[0].miny,iff_dlta_hdr->miny);
  1224.                          old_dlta[0].maxx =
  1225.                                 MAX(old_dlta[0].maxx,iff_dlta_hdr->maxx);
  1226.                          old_dlta[0].maxy =
  1227.                                 MAX(old_dlta[0].maxy,iff_dlta_hdr->maxy);
  1228.                          old_dlta[1].minx =
  1229.                                 MIN(old_dlta[1].minx,old_dlta[0].minx);
  1230.                          old_dlta[1].miny =
  1231.                                 MIN(old_dlta[1].miny,old_dlta[0].miny);
  1232.                          old_dlta[1].maxx =
  1233.                                 MAX(old_dlta[1].maxx,old_dlta[0].maxx);
  1234.                          old_dlta[1].maxy =
  1235.                                 MAX(old_dlta[1].maxy,old_dlta[0].maxy);
  1236.  
  1237.                   region_hdr = (ACT_REGION_HDR *) 
  1238.                  malloc( sizeof(ACT_REGION_HDR) + image_size );
  1239.              if (region_hdr==0)
  1240.                 TheEnd1("Buffer IFF: malloc error\0");
  1241.              act->data = (BYTE *) region_hdr;
  1242.              if (anim_flags & ANIM_HAM) 
  1243.                                  IFF_HAM_To_332(buff0,region_hdr->data);
  1244.              else    memcpy((void *)region_hdr->data,
  1245.                     (void *)buff0, image_size);
  1246.              if (optimize_flag == TRUE)
  1247.              {
  1248.                region_hdr->xpos = old_dlta[1].minx;
  1249.                region_hdr->ypos = old_dlta[1].miny;
  1250.                region_hdr->xsize = 
  1251.                   old_dlta[1].maxx - old_dlta[1].minx;
  1252.                region_hdr->ysize = 
  1253.                 old_dlta[1].maxy - old_dlta[1].miny;
  1254.              }
  1255.              else
  1256.              {
  1257.                region_hdr->xpos = 0;
  1258.                region_hdr->ypos = 0;
  1259.                region_hdr->xsize = imagex;
  1260.                region_hdr->ysize = imagey;
  1261.              }
  1262.                 
  1263.              act->type = ACT_REGION;
  1264.              tmp = buff0; buff0 = buff1; buff1 = tmp;
  1265.                          old_dlta[1].minx = old_dlta[0].minx;
  1266.                          old_dlta[1].miny = old_dlta[0].miny;
  1267.                          old_dlta[1].maxx = old_dlta[0].maxx;
  1268.                          old_dlta[1].maxy = old_dlta[0].maxy;
  1269.                          old_dlta[0].minx = iff_dlta_hdr->minx;
  1270.                          old_dlta[0].miny = iff_dlta_hdr->miny;
  1271.                          old_dlta[0].maxx = iff_dlta_hdr->maxx;
  1272.                          old_dlta[0].maxy = iff_dlta_hdr->maxy;
  1273.              free(iff_dlta_hdr);      /* free delta chunk */
  1274.             }
  1275.             break;
  1276.    case ACT_IFF_DLTA3:
  1277.             {
  1278.              ACT_IFF_DLTA_HDR *iff_dlta_hdr;
  1279.  
  1280.              iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
  1281.              IFF_Delta3(buff0,iff_dlta_hdr->data);
  1282.              free(act->data);         /* free delta chunk */
  1283.                   act->data = (BYTE *) malloc( image_size );
  1284.              if (anim_flags & ANIM_HAM) 
  1285.                      IFF_HAM_To_332(buff0,act->data);
  1286.              else              memcpy(act->data,buff0,image_size);
  1287.              act->type = ACT_IMAGE;
  1288.              tmp = buff0; buff0 = buff1; buff1 = tmp;
  1289.             }
  1290.             break;
  1291.    case ACT_IFF_DLTAl:
  1292.                         {
  1293.                          ACT_IFF_DLTA_HDR *iff_dlta_hdr;
  1294.  
  1295.                          iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
  1296.                          IFF_Deltal(buff0,iff_dlta_hdr->data,
  1297.                                                          1,iff_dlta_hdr);
  1298.                          free(act->data);         /* free delta chunk */
  1299.                          act->data = (BYTE *) malloc( image_size );
  1300.                          if (anim_flags & ANIM_HAM)
  1301.                                         IFF_HAM_To_332(buff0,act->data);
  1302.                          else           memcpy(act->data,buff0,image_size);
  1303.                          act->type = ACT_IMAGE;
  1304.                          tmp = buff0; buff0 = buff1; buff1 = tmp;
  1305.                         }
  1306.                         break;
  1307.  
  1308.    case ACT_IFF_DLTAJ:
  1309.             {
  1310.              ACT_IFF_DLTA_HDR *iff_dlta_hdr;
  1311.  
  1312.              iff_dlta_hdr = (ACT_IFF_DLTA_HDR *)(act->data);
  1313.              IFF_DeltaJ(buff0,iff_dlta_hdr->data,iff_dlta_hdr);
  1314.              free(act->data);         /* free delta chunk */
  1315.                   act->data = (BYTE *) malloc( image_size );
  1316.              if (anim_flags & ANIM_HAM) 
  1317.                  IFF_HAM_To_332(buff0,act->data);
  1318.              else          memcpy(act->data,buff0,image_size);
  1319.              act->type = ACT_IMAGE;
  1320.              tmp = buff0; buff0 = buff1; buff1 = tmp;
  1321.             }
  1322.             break;
  1323.    case ACT_IFF_HMAP:    
  1324.             {
  1325.              ColorReg *hptr;
  1326.              LONG i;
  1327.  
  1328.              hptr = (ColorReg *)act->data;
  1329.              for(i=0;i<HMAP_SIZE;i++)
  1330.              {
  1331.               ham_map[i].red   = hptr[i].red;
  1332.               ham_map[i].green = hptr[i].green;
  1333.               ham_map[i].blue  = hptr[i].blue;
  1334.              }
  1335.             }
  1336.             act->type = ACT_NOP;
  1337.             break;
  1338.   }
  1339.   i++;
  1340.  }
  1341. }
  1342.  
  1343. LONG IFF_DeltaJ(fptr,deltaptr,r_hdr)
  1344. UBYTE *fptr;
  1345. register UBYTE *deltaptr;
  1346. ACT_IFF_DLTA_HDR *r_hdr;
  1347. {
  1348.  register LONG rowsize,width;
  1349.  register UBYTE *imageptr;
  1350.  register LONG exitflag;
  1351.  register USHORT type,r_flag,b_cnt,g_cnt,r_cnt;
  1352.  register ULONG b,g,r;
  1353.  register ULONG offset,dmask,depth;
  1354.  register UBYTE data;
  1355.  LONG changed;
  1356.  LONG tmp,minx,miny,maxx,maxy;
  1357.  
  1358.  maxx=0;
  1359.  maxy=0;
  1360.  minx=imagex;
  1361.  miny=imagey;
  1362.  
  1363.  changed=0;
  1364.  width = imagex;
  1365.  rowsize = width / 8;
  1366.  exitflag=0;
  1367.  while(!exitflag)
  1368.  {
  1369.   /* read compression type and reversible_flag(xor data not just set) 
  1370.    */
  1371.   type   = (*deltaptr++) << 8; type   |= (*deltaptr++);
  1372.   r_flag = (*deltaptr++) << 8; r_flag |= (*deltaptr++);
  1373.   if (debug_flag) fprintf(stderr,"J type=%lx rev_flag=%lx imaged=%lx\n",type,r_flag,imaged);
  1374.  
  1375.   /* switch on compression type */
  1376.   switch(type)
  1377.   {
  1378.    case 0: exitflag = 1; break; /* end of list */
  1379.    case 1:
  1380.       /* Get byte count and group count 
  1381.        */
  1382.       b_cnt = (*deltaptr++) << 8; b_cnt |= (*deltaptr++);
  1383.       g_cnt = (*deltaptr++) << 8; g_cnt |= (*deltaptr++);
  1384.       if (debug_flag) fprintf(stderr,"byte group cnts %lx %lx\n",b_cnt,g_cnt);
  1385.       
  1386.       /* Loop thru groups
  1387.        */
  1388.       for(g=0;g<g_cnt;g++)
  1389.       {
  1390.         offset = (*deltaptr++) << 8; offset |= (*deltaptr++);
  1391.         if (debug_flag) fprintf(stderr,"  g%ld) offset=%lx\n",g,offset);
  1392.  
  1393.         offset <<= 3; /* counts bytes */
  1394.         imageptr = (UBYTE *)((ULONG)fptr + offset);
  1395.  
  1396.         tmp = offset%imagex; if (tmp<minx) minx=tmp;
  1397.         tmp += 8;            if (tmp>maxx) maxx=tmp;
  1398.         tmp = offset/imagex; if (tmp<miny) miny=tmp;
  1399.         tmp += b_cnt;        if (tmp>maxy) maxy=tmp;
  1400.        
  1401.         /* Loop thru byte count 
  1402.          */
  1403.         for(b=0; b < b_cnt; b++)
  1404.         {
  1405.           dmask = 1;
  1406.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1407.           {
  1408.             data = *deltaptr++;
  1409.             if (debug_flag) fprintf(stderr,"<%lx>",data);
  1410.             changed |= data;          /* CHECKFORZERO change */
  1411.             IFF_Byte_Mod(imageptr,data,dmask,r_flag);
  1412.             dmask <<= 1;
  1413.           } /* end of depth loop */
  1414.           if (debug_flag) fprintf(stderr,"\n");
  1415.           imageptr += width; /* direction is vertical */
  1416.         } /* end of byte loop */
  1417.       } /* end of group loop */
  1418.       break;
  1419.    case 2:
  1420.       /* Read row count, byte count and group count 
  1421.        */
  1422.       r_cnt = (*deltaptr++) << 8; r_cnt |= (*deltaptr++);
  1423.       b_cnt = (*deltaptr++) << 8; b_cnt |= (*deltaptr++);
  1424.       g_cnt = (*deltaptr++) << 8; g_cnt |= (*deltaptr++);
  1425.       if (debug_flag) fprintf(stderr,"row byte group cnts %lx %lx %lx\n",
  1426.                            r_cnt,b_cnt,g_cnt);
  1427.       
  1428.       /* Loop thru groups
  1429.        */
  1430.       for(g=0; g < g_cnt; g++)
  1431.       {
  1432.         offset = (*deltaptr++) << 8; offset |= (*deltaptr++);
  1433.         if (debug_flag) fprintf(stderr,"  g%ld) offset=%lx\n",g,offset);
  1434.         offset <<= 3; /* counts bytes */
  1435.  
  1436.         tmp = offset%imagex;     if (tmp<minx) minx=tmp;
  1437.         tmp += b_cnt * 8 + 8;    if (tmp>maxx) maxx=tmp;
  1438.         tmp = offset/imagex;     if (tmp<miny) miny=tmp;
  1439.         tmp += r_cnt;            if (tmp>maxy) maxy=tmp;
  1440.        
  1441.         /* Loop thru rows of group
  1442.          */
  1443.         for(r=0; r < r_cnt; r++)
  1444.         {
  1445.           if (debug_flag) fprintf(stderr,"     ROW%lx ++%ld,%ld++",r,
  1446.               (offset%width),(offset/width + r));
  1447.           dmask = 1;
  1448.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1449.           {
  1450.             imageptr = (UBYTE *)(fptr + offset + (r * width));
  1451.             for(b=0; b < b_cnt; b++) /* loop thru byte count */
  1452.             {
  1453.               data = *deltaptr++;
  1454.               if (debug_flag) fprintf(stderr,"<%lx>",data);
  1455.               changed |= data;        /* CHECKFORZERO */
  1456.            
  1457.               IFF_Byte_Mod(imageptr,data,dmask,r_flag);
  1458.               imageptr += 8;        /* data is horizontal */
  1459.             } /* end of byte loop */
  1460.             dmask <<= 1;
  1461.             if (debug_flag) fprintf(stderr,"((%lx))\n",depth);
  1462.           } /* end of depth loop */
  1463.         } /* end of row loop */
  1464.       } /* end of group loop */
  1465.       break;
  1466.    default: /* don't know this one yet */
  1467.             fprintf(stderr,"Unknown J-type %x\n",type);
  1468.             type = 0;      /* force an exit */
  1469.             exitflag = 1;
  1470.             break;
  1471.   } /* end of type switch */
  1472.  } /* end of while loop */
  1473.  
  1474.  r_hdr->minx = minx;
  1475.  r_hdr->miny = miny;
  1476.  r_hdr->maxx = maxx;
  1477.  r_hdr->maxy = maxy;
  1478.  
  1479.  if (r_hdr->minx >= imagex) r_hdr->minx = 0;
  1480.  if (r_hdr->miny >= imagey) r_hdr->miny = 0;
  1481.  if (r_hdr->maxx <= 0)      r_hdr->maxx = imagex;
  1482.  if (r_hdr->maxy <= 0)      r_hdr->maxy = imagey;
  1483.  if (debug_flag) fprintf(stderr,"xypos=<%ld,%ld> xysize=<%ld %ld>\n",
  1484.        r_hdr->minx,r_hdr->miny,r_hdr->maxx,r_hdr->maxy );
  1485.  
  1486.  /* if changed is zero then this Delta didn't change the image at all */ 
  1487.  return(changed);
  1488. } /* end of routine */
  1489.  
  1490. /* 
  1491.  *  Decode IFF type l anims
  1492.  */
  1493. void IFF_Deltal(fptr,deltaptr,vertflag,r_hdr)
  1494. UBYTE *fptr;
  1495. UBYTE *deltaptr;
  1496. LONG vertflag;
  1497. ACT_IFF_DLTA_HDR *r_hdr;
  1498. {
  1499.  register LONG i,depth,dmask,width;
  1500.  ULONG poff0,poff1;
  1501.  register UBYTE *imageptr;
  1502.  register UBYTE *optr,*dptr;
  1503.  register SHORT cnt;
  1504.  register USHORT offset,data;
  1505.  
  1506.  r_hdr->minx = 0;
  1507.  r_hdr->miny = 0;
  1508.  r_hdr->maxx = imagex;
  1509.  r_hdr->maxy = imagey;
  1510.  
  1511.  imageptr = fptr;
  1512.  if (vertflag) width = imagex;
  1513.  else width = 16;
  1514.  dmask = 1;
  1515.  for(depth = 0; depth<imaged; depth++)
  1516.  {
  1517.    imageptr = fptr;
  1518.    /*poff = planeoff[depth];*/ /* offset into delt chunk */
  1519.    poff0  = (deltaptr[ 4 * depth    ]) << 24;
  1520.    poff0 |= (deltaptr[ 4 * depth + 1]) << 16;
  1521.    poff0 |= (deltaptr[ 4 * depth + 2]) <<  8;
  1522.    poff0 |= (deltaptr[ 4 * depth + 3]);
  1523.  
  1524.    if (poff0)
  1525.    {
  1526.      poff1  = (deltaptr[ 4 * (depth+8)    ]) << 24;
  1527.      poff1 |= (deltaptr[ 4 * (depth+8) + 1]) << 16;
  1528.      poff1 |= (deltaptr[ 4 * (depth+8) + 2]) <<  8;
  1529.      poff1 |= (deltaptr[ 4 * (depth+8) + 3]);
  1530.  
  1531.      dptr = (UBYTE *)( (ULONG)(deltaptr) + 2 * poff0); 
  1532.      optr = (UBYTE *)( (ULONG)(deltaptr) + 2 * poff1); 
  1533.  
  1534.      /* while short *optr != -1 */
  1535.      while( (optr[0] != 0xff) || (optr[1] != 0xff) )
  1536.      {
  1537.        offset = (*optr++) << 8; offset |= (*optr++);
  1538.        cnt    = (*optr++) << 8; cnt    |= (*optr++);
  1539.  
  1540.        if (cnt < 0)  /* cnt negative */
  1541.        {
  1542.          imageptr = fptr + 16 * (ULONG)(offset);
  1543.          cnt = -cnt;
  1544.          data = (*dptr++) << 8; data |= (*dptr++);
  1545.          for(i=0; i < (ULONG)cnt; i++)
  1546.          {
  1547.            IFF_Short_Mod(imageptr,data,dmask,0);
  1548.            imageptr += width;
  1549.          }
  1550.        }  /* end of neg */
  1551.        else/* cnt pos then */
  1552.        {
  1553.          imageptr = fptr + 16 * (ULONG)(offset);
  1554.          for(i=0; i < (ULONG)cnt; i++)
  1555.          {
  1556.            data = (*dptr++) << 8; data |= (*dptr++);
  1557.            IFF_Short_Mod(imageptr,data,dmask,0);
  1558.            imageptr += width;
  1559.          }
  1560.        } /* end of pos */
  1561.      } /* end of delta for this plane */
  1562.    } /* plane has changed data */
  1563.    dmask <<= 1;
  1564.  } /* end of d */
  1565. }
  1566.  
  1567.  
  1568. /* Routine to read a little endian long word.
  1569.  * Note
  1570.  */
  1571. ULONG IFF_Get_Word(fp)
  1572. FILE *fp;
  1573. {
  1574.  ULONG ret;
  1575.  
  1576.  ret  = (fgetc(fp) & 0xff) << 24;
  1577.  ret |= (fgetc(fp) & 0xff) << 16;
  1578.  ret |= (fgetc(fp) & 0xff) << 8;
  1579.  ret |= (fgetc(fp) & 0xff);
  1580.  return ret;
  1581. }
  1582.  
  1583. /* Routine to read a little endian half word.
  1584.  */
  1585. ULONG IFF_Get_HalfWord(fp)
  1586. FILE *fp;
  1587. {
  1588.  ULONG ret;
  1589.  
  1590.  ret  = (fgetc(fp) & 0xff) << 8;
  1591.  ret |= (fgetc(fp) & 0xff);
  1592.  return ret;
  1593. }
  1594.  
  1595.